import java.util.HashMap;
import java.util.Set;

/**
 * author: MaHX
 * date: 2019/10/24/19:10
 * description:
 *
 * JDK7中的hashMap 对象数组+链表
 * resize:扩容为原来的两倍，但在扩容过程中容易出现死锁问题。
 *
 *
 * JDK7与JDK8中的区别
 * ①hash算法不一样，相比于7中左移右移减少
 * ②8中新节点加在原来节点的尾部
 * ③8中扩容不会出现死锁
 **/
public class MyHashMap<K, V> {
    private Entry[] table;
    private static Integer CAPACITY = 8;  //源码中容量为2的次方。
    private int size;
    private static float LOAD_FACTORY = 0.75f; //加载因子  阈值=长度*加载因子

    public MyHashMap() {
        table = new Entry[CAPACITY];
    }

    public int size() {
        return size;
    }

    public Object put(K k, V v) {
        Entry<K, V> newEntry = new Entry<>(k,v,null);
        int index = k.hashCode();  //hash进行多次左移，右移
        int i = index % CAPACITY;
        for (Entry<K, V> entry = table[i]; entry != null; entry = entry.next) {
            if (entry.k.equals(k)) {
                Object oldValue = entry.v;
                entry.v = v;
                return oldValue;
            }
        }

        addEntry(newEntry, i);
        return null;

    }

    private void addEntry(Entry<K, V> entry, int i) {
        entry.setNext(table[i]);
        table[i] = entry;
        size++;
    }

    /**
     * JDK7中的hash算法
     * @param h
     * @return
     */
    public int hash(int h,int length){
        return h&(length-1);
    }


    public Object get(Object key) {
        int index = key.hashCode();
        int i = index % CAPACITY;
        for (Entry<K,V> entry = table[i];entry != null;entry = entry.next){
            if (entry.k.equals(key)){
                return entry.v;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        MyHashMap<String,String> hashMap= new MyHashMap<>();
        HashMap<String,String> ss = new HashMap<>();
        hashMap.put("周瑜","学生");
        hashMap.put("曹操","总裁");
        hashMap.put("诸葛亮","军师");
        System.out.println(hashMap.get("周瑜"));
        System.out.println(hashMap.get("曹操"));
        System.out.println(hashMap.size());

    }

    class Entry<K, V> {
        private K k;
        private V v;
        private Entry next;

        public Entry(K k, V v, Entry next) {
            this.k = k;
            this.v = v;
            this.next = next;
        }

        public K getK() {
            return k;
        }

        public void setK(K k) {
            this.k = k;
        }

        public V getV() {
            return v;
        }

        public void setV(V v) {
            this.v = v;
        }

        public Entry getNext() {
            return next;
        }

        public void setNext(Entry next) {
            this.next = next;
        }
    }

}
